use yew::prelude::*;
use yew::services::fetch::FetchTask;

use crate::component::layout::Layout;
use crate::component::{ card, row, confirm::Confirm, pagination::Pagination };
use crate::error::Error;
use crate::service::user::UserService;
use crate::ob::user::{UserListPage, SysUser};
use crate::ob::ResultGraphql;

pub enum Action {
    Add,
    Edit(usize),
    DeleteConfirm(usize),
    Delete(usize),
    Refresh(u64),
    PageListDone(Result<ResultGraphql<UserListPage>, Error>),
    DeleteDone(Result<ResultGraphql<UserListPage>, Error>)
}

pub struct UserListView {
    link: ComponentLink<Self>,
    service: UserService,
    page: Option<UserListPage>,
    task: Option<FetchTask>,

    detail: Option<SysUser>,
    modal_id: &'static str,
    modal_title: &'static str,

    delete_confirm: crate::component::confirm::Props,

    page_done: Callback<Result<ResultGraphql<UserListPage>, Error>>,
    delete_done: Callback<Result<ResultGraphql<UserListPage>, Error>>
}

impl UserListView {
    /// 列表头
    fn header(&self) -> Html {
        let click = self.link.callback(|_| Action::Add);

        row(html! {
            <div class="d-flex justify-content-end">
                <button
                    onclick=click
                    class="btn btn-info btn-sm"
                    data-toggle="modal"
                    data-target=format!("#{}", self.modal_id)>{"添加"}</button>
            </div>
        })
    }
    /// 列表的列
    fn table(&self) -> Html {

        let page = {
            if let Some(p) = &self.page {
                html! { <Pagination
                    pageSize=p.findUserListPage.pageSize
                    pageNo=p.findUserListPage.pageNo
                    pages=p.findUserListPage.pages
                    total=p.findUserListPage.total
                    click=self.link.callback(Action::Refresh)
                    /> }
            } else { html! {} }
        };
        card(html! {
            <>
            { self.header() }
            <div class="table-responsive mt-1">
                <table class="table table-hover table-bordered">
                    <thead>
                        <tr>
                            <th>{"#"}</th>
                            <th>{"人员姓名"}</th>
                            <th>{"职位"}</th>
                            <th>{"创建时间"}</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>{ self.list() }</tbody>
                </table>
                { page }
            </div>
            </>
        })
    }
    /// 列表行
    fn list(&self) -> Html {
        let mut rs = html! {};
        if let Some(dt) = &self.page {
            rs = dt.findUserListPage.record.iter().enumerate().map(|(i, o)| {
                let edit = self.link.callback(move |_| Action::Edit(i));
                let delete = self.link.callback(move |_| Action::Delete(i));
                let pos = crate::USER_POS
                    .get(&o.position.unwrap_or(99))
                    .unwrap_or(&"");

                html! {
                    <tr>
                        <td>{ i + 1 }</td>
                        <td>{ o.name.as_ref().unwrap_or(&String::new()) }</td>
                        <td>{ pos }</td>
                        <td>{ crate::utils::datetime::from_timestamp(o.createTime) }</td>
                        <td style="width:120px;padding-top:8px;padding-bottom:0px">
                            <div class="d-flex justify-content-between">
                                <button
                                    onclick=edit
                                    class="btn btn-warning btn-sm"
                                    data-toggle="modal"
                                    data-target=format!("#{}", self.modal_id)
                                    type="button">{"编辑"}</button>
                                <button
                                    onclick=delete
                                    class="btn btn-danger btn-sm"
                                    data-toggle="modal"
                                    data-target=format!("#{}", self.delete_confirm.id)
                                    type="button">{"删除"}</button>
                            </div>
                        </td>
                    </tr>
                }
            }).collect();
        }
        rs
    }
    /// 删除人员
    fn delete(&mut self, i: usize) {
        if let Some(p) = &self.page {
            if let Some(ob) = p.findUserListPage.record.get(i) {
                self.task = Some(self.service.delete(ob.id.unwrap(), self.delete_done.clone()))
            }
        }
    }
}

impl Component for UserListView {
    type Message = Action;
    type Properties = ();

    fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
        Self {
            page_done: link.callback(Action::PageListDone),
            delete_done: link.callback(Action::DeleteDone),

            service: UserService::new(),
            task: None, page: None, detail: None,
            modal_id: "user_detail",
            modal_title: "",
            delete_confirm: crate::component::confirm::Props {
                id: "user_delete_confirm",
                index: usize::MIN,
                then: link.callback(|x| Action::DeleteConfirm(x))
            },
            link
        }
    }

    fn update(&mut self, msg: Self::Message) -> bool {
        match msg {
            Action::PageListDone(res) => {
                self.task = None;
                match res {
                    Ok(v) => self.page = Some(v.data),
                    Err(e) => crate::error(format!("{:?}", e).as_str())
                };
                self.page.is_some()
            },
            Action::Add => {
                self.modal_title = "添加人员";
                self.detail = None;
                true
            },
            Action::Edit(i) => {
                if let Some(p) = &self.page {
                    let u = p.findUserListPage.record.get(i);
                    self.modal_title = "编辑人员";
                    self.detail = u.cloned();
                }
                true
            },
            Action::DeleteConfirm(i) => {
                self.delete(i);
                false
            },
            Action::Delete(i) => {
                self.delete_confirm.index = i;
                true
            },
            Action::DeleteDone(res) => {
                self.task = None;
                crate::close_modal(&self.delete_confirm.id);
                match res {
                    Ok(v) => self.page = Some(v.data),
                    Err(e) => crate::error(format!("{:?}", e).as_str())
                };
                crate::swl_message(true, "删除成功！", "");
                self.page.is_some()
            }
            Action::Refresh(p) => {
                self.task = Some(self.service.list_page(p, self.page_done.clone()));
                true
            }
        }
    }

    fn change(&mut self, _: Self::Properties) -> bool {
        false
    }

    fn view(&self) -> Html {
        use crate::view::user::detail::UserDetailView;
        html! {
            <>
                <Layout />
                <main class="app-content">
                    <div class="app-title">
                        <div>
                            <h1><i class="fa fa-dashboard"></i>{" 人员"}</h1>
                            <p>{"所有人员信息"}</p>
                        </div>
                        <ul class="app-breadcrumb breadcrumb">
                            <li class="breadcrumb-item"><i class="fa fa-home fa-lg"></i></li>
                            <li class="breadcrumb-item"><a href="#">{"人员"}</a></li>
                        </ul>
                    </div>
                    {self.table()}
                    <UserDetailView
                        id=self.modal_id
                        title=self.modal_title
                        data=self.detail.clone()
                        call=self.page_done.clone() />

                    <Confirm id=self.delete_confirm.id
                        index=self.delete_confirm.index
                        then=self.delete_confirm.then.clone() />
                </main>
            </>
        }
    }

    fn rendered(&mut self, is_first: bool) {
        if is_first {
            self.task = Some(self.service.list_page(1, self.page_done.clone()));
        }
    }
}